曾經我在資料夾開好 laravel 專案後,一時不知道從哪裡下手……所以後來我大概都依照下面順序進行,不過每個人不同,下面順序也不一定是上下有相關,可以參考參考就好XD
.env 編輯
參考 ER Diagram 編輯 migration、定義各欄位結構
測試:
如果有異動 migration,務必執行看看、也測試看看 rollback,只執行migrate而忽略 rollback的話,rollback 錯誤是不會顯示出來的!
編輯 model 檔案
建立 routes, controller, view 或處理回覆的 resource, collection 等檔案
依照上面的開發順序,昨天大概是進行到第三點結束,還沒有編輯 Model 檔案,所以今日要來進行 Model 檔案編輯,並用 Seeder 建立資料。
每個主要功能其實就如同上圖,不外乎 index, create, store, show, edit, update, destroy 七種功能。今天我們就來嘗試用 團購 Group 建立其中的三種功能 index, show, destroy 吧!
備註:這七種功能的稱呼方式可以說是工程師彼此間溝通的術語,講 index 大家就知道你說的功能是什麼,所以可以儘早熟悉一下,也是我做這張圖的目的。
檔案路徑:app/Models/Group.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Group extends Model
{
use HasFactory;
const STATUS_NOT_STARTED = 0; // 未開團
const STATUS_OPEN = 1; // 開團中
const STATUS_CLOSE = 2; // 結團處理中
const STATUS_DELIVERED = 3; // 運送取貨中
protected $fillable = [
'id',
'group_name',
'organizer_id',
'close_price',
'close_date',
'allow_insert_product',
'status',
];
protected $casts = [
'created_at' => 'datetime:Y-m-d H:i:s',
'updated_at' => 'datetime:Y-m-d H:i:s',
];
}
一般基本的 Model 檔案大概分成幾個區塊:
$fillable & $guarded 就像白名單與黑名單之間的關係。
$fillable
屬性用於定義哪些模型的屬性可以被大量賦值(Mass Assigned)。只有在 $fillable
中列出的屬性才能夠被大量賦值,其他屬性將被自動保護(Guarded)。$guarded
屬性用於定義哪些模型的屬性應該受到保護,不允許大量賦值。只有列在 $guarded
中的屬性會被保護,其他屬性可以被大量賦值。通常這兩個會擇一使用,我自己在專案中都是使用 $fillable
,而且多是從 migration 把欄位名稱直接複製過來修改。
很多時候資料表裡面會有 狀態 status, 性別sex, 分類等欄位,這些欄位常用 0~9 這些整數代表不同的意思,例如:0 = 未開團、1 = 開團中等狀態,這個邏輯可能是前後端一起討論出來一起定義的,所以可能會在程式碼的任何地方用到。
菜鳥提問:幹嘛不直接存 “open”、”close”這種字,還要用數字代替?
欄位少的話的確可以,也有資料庫使用偏好存英文字在裡面的,我自己是覺得 數字比英文來得比較明顯正確或錯誤,資料庫搜尋每個欄位的值所消耗的時間或動所也比較少跟簡單。
為了後續維護時,0 需要改成「關閉中」,進而衍生出你要在整個專案中搜尋所有用到的地方然後修改這種麻煩事,我們會在專案裡面以常數的方式定義,屆時只要修改 Model 裡面即可。
// model 裡面定義
const STATUS_NOT_STARTED = 0; // 未開團
const STATUS_OPEN = 1; // 開團中
const STATUS_CLOSE = 2; // 結團處理中
const STATUS_DELIVERED = 3; // 運送取貨中
// controller 裡面使用
Group::where('status', STATUS_OPEN)->get();
其他優點包括:
status
欄位的值可以是 0、1、2 或 3,但在代碼中,可以使用常數 STATUS_NOT_STARTED
來表示未開團的狀態。STATUS_OPEN
時,立即知道它表示一個開團中的狀態,而不需要記住或查閱數字代碼的含義。如同昨天所說,為了避免一直重複資料,所以我先建了 seeder 檔案,讓我們等一下要開發的功能可以取得資料
namespace Database\Seeders;
use App\Models\Group;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class GroupSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
DB::table('groups')->truncate();
// 先刪除所有資料,避免操作中有很多重複的麥當勞XD
DB::table('groups')->insert([
'group_name' => '麥當勞',
'organizer_id' => rand(1, 3),
'close_price' => 1000,
'close_date' => null,
'allow_insert_product' => true,
'status' => Group::STATUS_OPEN,
// 取用剛剛 model 定義的常數
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('groups')->insert([
'group_name' => '肯德基',
'organizer_id' => rand(1, 3),
'close_price' => 1000,
'close_date' => null,
'allow_insert_product' => true,
'status' => Group::STATUS_OPEN,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('groups')->insert([
'group_name' => fake()->company,
// 使用 fake() 產生隨機資料
'organizer_id' => rand(1, 3),
'close_price' => 1000,
'close_date' => null,
'allow_insert_product' => true,
'status' => Group::STATUS_OPEN,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
seeder 的官方文件還算滿簡單好懂,這邊就不多介紹。
除了官方文件所教,可以一筆一筆產生資料外,實務開發上也會加入一些判斷式,例如:
因此這裡我用了 truncate() ,即使資料表裡面已經有資料,我還是先把所有資料刪除,然後執行 seeder,才不會在測試 seeder 內容時看到好多好多麥當勞~
官方文件:https://fakerphp.github.io
Laravel 內建有使用 faker 套件,可快速產生一些 firstName, address, text 等等資料
需要的時候可以用 fake() 函式,參考官方文件也可找到
如果要讓 fake() 產生的假資料為中文,要到 config/app.php 把下面這行改成 zh_TW
// 預設
'faker_locale' => 'en_US',
// 中文化
'faker_locale' => 'zh_TW',